﻿using Common.Logging;
using Microsoft.WindowsAzure.Storage;
using Microsoft.WindowsAzure.Storage.Table;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using WebDAVSharp.Server;
using WebDAVSharp.Server.Adapters;
using WebDAVSharp.Server.Stores.DiskStore;

namespace AzureStorageLight
{
    class Program
    {
        static void Main(string[] args)
        {
            var mode = "webdav";
            var dictionary = new Dictionary<string, string>();
            for (int index = 0; index < args.Length - 1; index += 2)
            {
                dictionary.Add(args[index].ToLower(), args[index + 1]);
            }

            if (dictionary.ContainsKey("/mode"))
            {
                mode = dictionary["/mode"].ToLower();
            }

            if ((mode == "webdav" || mode == "backup" || mode == "restore" || mode == "createticket")
                && dictionary.ContainsKey("/connection") || dictionary.ContainsKey("/ticket"))
            {
                if (dictionary.ContainsKey("/connection"))
                {
                    StorageConfig.Instance.ConnectionString = dictionary["/connection"];
                }
                if (dictionary.ContainsKey("/itemstablename"))
                {
                    StorageConfig.Instance.ItemTableName = dictionary["/itemstablename"];
                }
                else
                {
                    StorageConfig.Instance.ItemTableName = "folders";
                }

                if (dictionary.ContainsKey("/fileblobcontainer"))
                {
                    StorageConfig.Instance.FileBlobContainer = dictionary["/fileblobcontainer"];
                }
                else
                {
                    StorageConfig.Instance.FileBlobContainer = "files";
                }

                if (dictionary.ContainsKey("/backupblobcontainer"))
                {
                    StorageConfig.Instance.BackupBlobContainer = dictionary["/backupblobcontainer"];
                }
                else
                {
                    StorageConfig.Instance.BackupBlobContainer = "backup";
                }

                if (dictionary.ContainsKey("/portno"))
                {
                    StorageConfig.Instance.PortNo = int.Parse(dictionary["/portno"]);
                }
                else
                {
                    StorageConfig.Instance.PortNo = 10443; ;
                }

                if (dictionary.ContainsKey("/ticketspan"))
                {
                    StorageConfig.Instance.TicketSpan = int.Parse(dictionary["/ticketspan"]);
                }
                else
                {
                    StorageConfig.Instance.TicketSpan = 24*180;
                }

                if (dictionary.ContainsKey("/password"))
                {
                    StorageConfig.Instance.TicketPassword = dictionary["/password"];
                }

                var port = StorageConfig.Instance.PortNo.ToString();
                var url = "http://localhost:" + port + "/";
                var drive = "\\\\localhost@" + port + "\\DavWWWRoot";

                if (dictionary.ContainsKey("/log"))
                {
                    if (dictionary["/log"].ToLower() == "on")
                    {
                        LogManager.Adapter = new
                            Common.Logging.Simple.ConsoleOutLoggerFactoryAdapter();
                    }
                }

                StorageItemManager mng;
                 
                if (dictionary.ContainsKey("/ticket"))
                {
                    StorageConfig.Instance.Ticket = dictionary["/ticket"];
                    if (StorageConfig.Instance.TicketPassword != null)
                    {
                        StorageConfig.Instance.Ticket = CryptUtil.DecryptStringAES(StorageConfig.Instance.Ticket, StorageConfig.Instance.TicketPassword);
                    }
                }
                mng = StorageItemManager.CreateStorageItemManager(StorageConfig.Instance);
                mng.EnsureItem("/").Wait();
                Directory.CreateDirectory(StorageItemManager.ApplicationFolder);

                switch (mode)
                {
                    case "webdav":
                        try
                        {
                            WebDavServer server = new WebDavServer(new AppWebDavStore());
                            server.Start(url);
                            Process.Start(drive);
                        }
                        finally
                        {
                            StorageItemManager.WaitAsyncTasks();
                        }
                        break;
                    case "backup":
                        mng.BackupAsync().Wait();
                        var hist = new TimeSpan[] { new TimeSpan(1, 0, 0), new TimeSpan(1, 0, 0, 0), new TimeSpan(10, 0, 0, 0), new TimeSpan(30, 0, 0, 0), };
                        mng.PurgeBackupAsync(hist).Wait();
                        break;
                    case "restore":
                        WebDavServer restoreServer = new WebDavServer(new BackupWebDavStore());
                        restoreServer.Start(url);
                        Process.Start(drive);
                        break;
                    case "createticket":
                        var ticket = StorageItemManager.CreateTicket(
                            StorageConfig.Instance.ConnectionString,
                            StorageConfig.Instance.ItemTableName,
                            StorageConfig.Instance.FileBlobContainer,
                            StorageConfig.Instance.BackupBlobContainer,
                            DateTime.UtcNow.AddHours(StorageConfig.Instance.TicketSpan),
                            StorageConfig.Instance.TicketPassword
                            );
                        Console.WriteLine(ticket);
                        break;
                }

            }
            else
            {
                Console.WriteLine("option");
                Console.WriteLine("  /mode webdav(default) | backup | restore | createticket \"");
                Console.WriteLine("  /connection \"azure storage connection string\"");
                Console.WriteLine("  /itemsTableName \"table name for items\" -- folders(default)");
                Console.WriteLine("  /fileBlobContainer \"blob container name for files\" -- files(default)");
                Console.WriteLine("  /backupBlobContainer \"blob container name for backup\" -- backup(default)");
                Console.WriteLine("  /portno \"port no for webdav\"");
                Console.WriteLine("  /ticket \"access ticket\"");
                Console.WriteLine("  /ticketspan \"available hours of ticket. -- 4320(default 180 days)\"");
                Console.WriteLine("  /password \"ticket password\"");
                Console.WriteLine("");
                Console.WriteLine("example");
                Console.WriteLine("  /mode webdav /connection \"Default...\"");
                Console.WriteLine("  /mode backup /connection \"Default...\" /backupBlobContainer \"Default...\"");
                Console.WriteLine("  /mode createticket /password passw0rd /connection \"Default...\"");
                Console.WriteLine("  /password passw0rd /ticket \"EAAAADkNg3...\"");
            }

        }

    }
}